package com.db.concurrency;

public class VolatileImmutableCacheImpl<K, V> implements Cache<K, V> {

  private volatile ImmutableCache<K, V> immutableCache;
  
  public VolatileImmutableCacheImpl() {
    immutableCache = new ImmutableCache<>();
  }

  @Override
  public V get(K key) {
    if (key == null) {
      throw new NullPointerException();
    }
    ImmutableCache<K, V> localImmutableCache = immutableCache;
    return key.equals(localImmutableCache.getKey()) ? localImmutableCache.getValue() : null;
  }

  @Override
  public void put(K key, V value) {
    if (key == null) {
      throw new NullPointerException();
    }
    immutableCache = immutableCache.newImmutableCache(key, value);
  }

}

class ImmutableCache<K, V> {
  
  private final K key;
  private final V value;
  
  ImmutableCache() {
    this.key = null;
    this.value = null;
  }
  
  ImmutableCache(K key, V value) {
    this.key = key;
    this.value = value;
  }
  
  public K getKey() {
    return key;
  }

  public V getValue() {
    return value;
  }
  
  public ImmutableCache<K, V> newImmutableCache(K key, V value) {
    return new ImmutableCache<>(key, value);
  }
}